<script setup>
import {computed, ref} from "vue";
import CommentImage from "@/views/Article/CommentImage.vue";
import Avatar from "@/components/Avatar.vue"
import {commentAPI} from "@/apis/index.js";
import {ElMessage} from "element-plus";

const props = defineProps({
  articleId: {
    type: Number,
  },
  pCommentId: {
    type: Number,
  },
  replyUserId: {
    type: Number,
  },
  userInfo: {
    type: Object,
  },
  allowComment: {
    type: Boolean,
  }
});

// 定义事件
const emit = defineEmits(['comment-published']);

const formDataRef = ref(null);

const checkPostComment = (rule, value, callback) => {
  // 检查内容是否为空或只包含空白字符
  const hasContent = value && value.trim().length > 0;
  // 检查是否有图片
  const hasImage = formData.value.image != null;

  if (!hasContent && !hasImage) {
    callback(new Error("Please input comment content or upload an image"));
  } else {
    callback();
  }
};

const rules = {
  content: [
    { validator: checkPostComment, trigger: 'blur' },
  ],
};

const formData = ref({});
const commentImg = ref(null);
const selectedImageFile = ref(null); // 存储选择的图片文件
const uploadingImg = ref(false); // 图片上传状态

// 图片选择处理
const handleImageUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isImage) {
    ElMessage.error('Only image files can be uploaded!')
    return false
  }
  if (!isLt5M) {
    ElMessage.error('Image size cannot exceed 5MB!')
    return false
  }

  // 存储文件对象，用于后续上传
  selectedImageFile.value = file
  
  // 创建预览URL
  const reader = new FileReader()
  reader.onload = (e) => {
    commentImg.value = e.target.result
  }
  reader.readAsDataURL(file)
  
  return false
}

// 删除图片
const removeImage = () => {
  // 清除预览和文件引用
  commentImg.value = null;
  selectedImageFile.value = null;
}

// 上传图片到服务器
const uploadImageToServer = async () => {
  if (!selectedImageFile.value) {
    return null;
  }

  try {
    uploadingImg.value = true;
    
    // 创建 FormData 对象
    const formData = new FormData()
    formData.append('image', selectedImageFile.value)

    // 调用上传接口
    const response = await commentAPI.uploadCommentImage(formData)

    if (response.status === 'success') {
      return response.data.imageUrl;
    }
    return null;
  } catch (error) {
    console.log(error)
    ElMessage.error('Image upload failed!')
    return null;
  } finally {
    uploadingImg.value = false;
  }
}

// 发表评论
const postCommentDo = async () => {
  // 表单校验
  if (!formDataRef.value) {
    ElMessage.error("Form reference not found");
    return;
  }
  
  try {
    // 执行表单校验
    await formDataRef.value.validate();
  } catch (error) {
    // 校验失败，不执行提交
    return;
  }
  
  // 如果有选择的图片，先上传图片
  let imageUrl = null;
  if (selectedImageFile.value) {
    imageUrl = await uploadImageToServer();
    if (selectedImageFile.value && !imageUrl) {
      // 图片上传失败，不继续提交评论
      return;
    }
  }
  
  const data = {
    userId: props.userInfo.userId,
    articleId: props.articleId,
    pCommentId: props.pCommentId,
    replyUserId: props.replyUserId,
    content: formData.value.content
  }
  
  // 如果有图片URL，添加到请求数据中
  if (imageUrl) {
    data.image = imageUrl;
  }
  
  try {
    const response = await commentAPI.publishComment(data)
    if (response.status === 'success') {
      ElMessage.success("Comment successful");
      // 重置表单
      resetForm();
      // 触发评论发布完成事件
      emit('comment-published');
    }
  } catch (error) {
    console.log(error)
  }
}

// 重置表单
const resetForm = () => {
  formData.value = {};
  commentImg.value = null;
  selectedImageFile.value = null;
  if (formDataRef.value) {
    formDataRef.value.resetFields();
  }
}
</script>

<template>
  <div class="post-comment-panel">
    <div class="comment-form" v-if="userInfo.userId && allowComment">
      <Avatar :width="50" :src="userInfo.avatar"></Avatar>
      <el-form :model="formData" :rules="rules" ref="formDataRef" class="input-form">
        <!--textarea输入-->
        <el-form-item prop="content">
          <el-input
              clearable
              placeholder="Please input comment"
              type="textarea"
              :maxlength="800"
              resize="none"
              :rows="3"
              show-word-limit
              v-model="formData.content"
          ></el-input>
          <div class="insert-img">
            <div class="pre-img" v-if="commentImg">
              <CommentImage :src="commentImg"></CommentImage>
              <el-icon class="remove-icon" @click="removeImage"><CircleCloseFilled /></el-icon>
            </div>
            <el-upload
                v-else
                :before-upload="handleImageUpload"
                name="file"
                :show-file-list="false"
                accept="image/*"
                :multiple="false"
            >
              <el-icon size="24"><PictureFilled /></el-icon>
              <span>Upload image</span>
            </el-upload>
          </div>
        </el-form-item>
      </el-form>
      <el-button 
        type="primary" 
        class="send-btn" 
        @click="postCommentDo"
        v-loading="uploadingImg"
      >
        <span>Publish</span>
      </el-button>
    </div>
    <div class="post-no-login" v-else-if="allowComment">
      <span>Please login to leave a comment</span>
    </div>
    <div class="post-no-login" v-else>
      <span>This post does not allow comment</span>
    </div>
  </div>
</template>

<style scoped lang="scss">
.post-comment-panel {
  .comment-form {
    display: flex;
    width: 100%;
    .input-form {
      margin-left: 20px;
      flex: 1;
    }
    .insert-img {
      line-height: normal;
      .pre-img {
        margin-top: 15px;
        position: relative;
        .remove-icon {
          cursor: pointer;
          position: absolute;
          top: -10px;
          right: -10px;
          font-size: 20px;
        }
      }
    }
    .send-btn {
      margin-left: 20px;
      width: 90px;
      height: 73px;
      text-align: center;
      line-height: 60px;
      border-radius: 5px;
      font-size: 18px;
    }
  }
  .post-no-login {
    font-size: 18px;
    font-weight: 600;
  }
}
</style>